"""
本模块包括PistonCluster类，可以模拟Minecraft粘性活塞的行为。
"""


from typing import *


class PistonCluster:
    def __init__(self):
        self.pist = []
        self.NoP: int = 0

    def set(self, NoP: int):
        self.NoP = NoP
        self.pist.clear()
        self.pist.extend(1 for i in range(NoP))
        self.pist.append(4)
        self.pist.extend(0 for i in range(NoP + 1))
        return self
    
    def set_l(self, NoP: int):
        self.NoP = NoP
        self.pist = [0 if i % 2 else 1 for i in range(0,NoP*2)]
        self.pist.extend([4,0])
        return self

    def trig(self, IoP: int):
        if IoP in range(0, len(self.pist)):
            if self.pist[IoP] == 1:
                if self.pist[IoP + 1] == 0 and self.pist[IoP + 2] != 2:
                    self.pist[IoP + 1] = self.pist[IoP + 2]
                    self.pist[IoP + 2] = 0
                else:
                    if self.pist[IoP:].count(3):
                        if self.pist[IoP:].index(0) < self.pist[IoP:].index(3):
                            self.pist.pop(IoP + self.pist[IoP:].index(0))
                            self.pist.insert(IoP + 1, 0)
                    else:
                        self.pist.pop(IoP + self.pist[IoP:].index(0))
                        self.pist.insert(IoP + 1, 0)

        return self

    def toggle(self, IoP: int):
        if self.pist[IoP] == 1:
            if self.pist[IoP + 1] == 0:
                self.pist[IoP + 1] = 3
                self.pist[IoP] = 2
            else:
                if self.pist[IoP:].count(3):
                    if self.pist[IoP:].index(0) < self.pist[IoP:].index(3):
                        self.pist.pop(IoP + self.pist[IoP:].index(0))
                        self.pist.insert(IoP + 1, 2)
                        self.pist[IoP] = 2
                else:
                    self.pist.pop(IoP + self.pist[IoP:].index(0))
                    self.pist.insert(IoP + 1, 3)
                    self.pist[IoP] = 2

        elif self.pist[IoP] == 2:
            self.pist[IoP] = 1
            if self.pist[IoP + 2] != 2:
                self.pist[IoP + 1] = self.pist[IoP + 2]
                self.pist[IoP + 2] = 0
            else:
                self.pist[IoP + 1] = 0

    def getState(self) -> str:
        rst = []
        for i in self.pist:
            if i == 1:
                rst.append("P")
            elif i == 2:
                rst.append("E")
            elif i == 3:
                rst.append("-")
            elif i == 0:
                rst.append(" ")
            else:
                rst.append("O")
        return "".join(rst)

    def getValidRange(self) -> range:
        return range(0, self.pist.index(4))

    def isCompat(self) -> bool:
        return self.pist[self.NoP] == 4

    def isLoof(self) -> bool:
        for i in range(1, self.NoP * 2 + 1, 2):
            if self.pist[i] != 0:
                return False
        return self.pist[self.NoP * 2] == 4

    def performInstructions(self, ins: List[int]) -> None:
        for i in ins:
            self.trig(i)

    pass
